package com.billy.ohos.swipe.internal;

import com.ryan.ohos.extension.ComponentPositionHelper;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentParent;
import ohos.agp.components.ListContainer;
import ohos.agp.utils.Rect;

/**
 * @author billy.qi
 * @since 2019-05-23 11:25
 */
public class ViewCompat {
    /**
     * Indicates that the input type for the gesture is from a user touching the screen.
     */
    public static final int TYPE_TOUCH = 0;
    /**
     * Indicates that the input type for the gesture is caused by something which is not a user
     * touching a screen. This is usually from a fling which is settling.
     */
    public static final int TYPE_NON_TOUCH = 1;
    /**
     * Indicates no axis of view scrolling.
     */
    public static final int SCROLL_AXIS_NONE = 0;
    /**
     * Indicates scrolling along the horizontal axis.
     */
    public static final int SCROLL_AXIS_HORIZONTAL = 1 << 0;
    /**
     * Indicates scrolling along the vertical axis.
     */
    public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
    private static ThreadLocal<Rect> sThreadLocalRect;

    private static Rect getEmptyTempRect() {
        if (sThreadLocalRect == null) {
            sThreadLocalRect = new ThreadLocal<>();
        }
        Rect rect = sThreadLocalRect.get();
        if (rect == null) {
            rect = new Rect();
            sThreadLocalRect.set(rect);
        }
//        rect.setEmpty();
        rect.clear();
//        rect.left = right = top = bottom = 0;
        return rect;
    }

    /**
     * <p>Cause an invalidate to happen on the next animation time step, typically the
     * next display frame.</p>
     *
     * <p>This method can be invoked from outside of the UI thread
     * only when this View is attached to a window.</p>
     *
     * @param view View to invalidate
     */
    public static void postInvalidateOnAnimation(Component view) {
        view.getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                view.invalidate();
            }
        });
    }

    /**
     * Offset this view's vertical location by the specified number of pixels.
     *
     * @param view   view
     * @param offset the number of pixels to offset the view by
     */
    public static void offsetTopAndBottom(Component view, int offset) {
        if (view == null || offset == 0) {
            return;
        }
        view.getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                ComponentPositionHelper.offsetTopAndBottom(view, offset);
            }
        });
    }

    private static void compatOffsetTopAndBottom(Component view, int offset) {
        ComponentPositionHelper.offsetTopAndBottom(view, offset);
        if (view.getVisibility() == Component.VISIBLE) {
            tickleInvalidationFlag(view);

            ComponentParent parent = view.getComponentParent();
            if (parent instanceof Component) {
                tickleInvalidationFlag((Component) parent);
            }
        }
    }

    /**
     * Offset this view's horizontal location by the specified amount of pixels.
     *
     * @param view   view
     * @param offset the number of pixels to offset the view by
     */
    public static void offsetLeftAndRight(Component view, int offset) {
        if (view == null || offset == 0) {
            return;
        }
        LogUtil.loge("offsetTopAndBottom", "offsetLeftAndRight  =======" + offset);
        view.getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                ComponentPositionHelper.offsetLeftAndRight(view, offset);
            }
        });
    }

    private static void compatOffsetLeftAndRight(Component view, int offset) {
        ComponentPositionHelper.offsetLeftAndRight(view, offset);
        if (view.getVisibility() == Component.VISIBLE) {
            tickleInvalidationFlag(view);
            ComponentParent parent = view.getComponentParent();
            if (parent instanceof Component) {
                tickleInvalidationFlag((Component) parent);
            }
        }
    }

    private static void tickleInvalidationFlag(Component view) {
        final float yP = view.getContentPositionY();
        view.setContentPositionY(yP + 1);
        view.setContentPositionY(yP);
    }

    public static Component.LayoutDirection getLayoutDirection(Component view) {
        return view.getLayoutDirection();
    }

    /**
     * Check if the items in the list can be scrolled in a certain direction.
     *
     * @param listView  listView
     * @param direction Negative to check scrolling up, positive to check
     *                  scrolling down.
     * @return true if the list can be scrolled in the specified direction,
     * false otherwise.
     */
    public static boolean canListViewScrollVertical(ListContainer listView, int direction) {
        return listView.canScroll(direction);
    }
}
